﻿// iotest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include "io/io.h"
#include "gc/gc.h"
#include "process/processor.h"


class my_packet_factory : public eyas::io::packet_factory_base{
public:
	class packet_decoder : public eyas::io::packet_decoder_base{
	public:
		packet_decoder(){
			printf("packet_decoder construct\n");
		}
		virtual ~packet_decoder(){
			printf("packet_decoder destruct\n");
		}
	private:
		eyas::buffer::iobuffer buffer_;
	public:
		virtual int32_t advance_recv_buffer(){
			return 12;
		}
		// 收到数据调用
		// return true:数据包完整  false:异常，须断开连接
		virtual bool decode(eyas::buffer::iobuffer& buffer){
			this->buffer_.clear();
			this->buffer_.push(buffer);
			buffer.clear();
			return true;
		}
		// 数据
		virtual eyas::buffer::iobuffer& data(){
			return buffer_;
		}
	};
	class packet_encoder : public eyas::io::packet_encoder_base{
	public:
		packet_encoder(){
			printf("packet_encoder construct\n");
		}
		virtual ~packet_encoder(){
			printf("packet_encoder destruct\n");
		}
	public:
		 virtual void encode(eyas::buffer::iobuffer& buffer){

		 }
	};
	my_packet_factory(){
		printf("my_packet_factory construct\n");
	}
	virtual ~my_packet_factory(){
		printf("my_packet_factory destruct\n");
	}
	/**
	 * 创建解析器
	 */
	virtual eyas::io::packet_decoder_ptr create_packet_decoder(){
		return eyas::gc::create_new<packet_decoder>();
	}
	/**
	 * 创建封装器
	 */
	virtual eyas::io::packet_encoder_ptr create_packet_encoder(){
		return eyas::gc::create_new<packet_encoder>();
	}
};

class my_data_handler : public eyas::io::data_handler_base{
public:
	my_data_handler(){
		printf("my_data_handler construct\n");
	}
	virtual ~my_data_handler(){
		printf("my_data_handler destruct\n");
	}
public:
	virtual void on_data_received(eyas::io::packet_decoder_ptr& packet){
		eyas::buffer::iobuffer_slices_ptr slicesPtr = packet->data().pop();
		printf("received size:%d,data:%s\n", slicesPtr->length(), slicesPtr->get_read_buffer());
	}
};

class packet : public eyas::io::packet_encoder_base{
public:
	virtual void encode(eyas::buffer::iobuffer& buffer){
		buffer.get_writer().write("hello world", 12);
	}
};

class my_connection_handler : public eyas::io::connection_handler_base, public boost::enable_shared_from_this<my_connection_handler>{
public:
	my_connection_handler(){
		printf("my_connection_handler construct\n");
	}
	virtual ~my_connection_handler(){
		printf("my_connection_handler destruct\n");
	}

	void test_send(){
		if(nullptr != this->connectionPtr_){
			this->connectionPtr_->write(packet());
		}
	}

	eyas::io::connection_ptr connectionPtr_;
	eyas::process::timer_ptr timer_;
public:
	virtual void on_connected(eyas::io::connection_ptr connectionPtr){
		printf("on_connected\n");
		connectionPtr->launch(eyas::gc::create_new<my_data_handler>(), eyas::gc::create_new<my_packet_factory>());
		connectionPtr_ = connectionPtr;
		timer_ = eyas::process::fly_timer(100, 100, &my_connection_handler::test_send, this->shared_from_this());
	}
	virtual void on_closed(eyas::io::connection_ptr connectionPtr, const eyas::io::error_code& error){
		printf("on_closed\n");
		timer_->cancel();
		timer_ = nullptr;
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	eyas::process::init();
	eyas::io::init();

	eyas::io::tcp_client_ptr clientPtr = eyas::io::create_tcp_client();
	eyas::io::tcp_server_ptr serverPtr = eyas::io::create_tcp_server();

	serverPtr->open("127.0.0.1", 9000, eyas::gc::create_new<my_connection_handler>());
	::Sleep(1000);
	clientPtr->open("127.0.0.1", 9000, eyas::gc::create_new<my_connection_handler>());

	getchar();

	//clientPtr->close();
	//serverPtr->close();
	return 0;
}

